<?php

/*
	[Discuz!] (C)2001-2007 Comsenz Inc.
	This is NOT a freeware, use is subject to license terms

	$Id: ftp.func.php 9806 2007-08-15 06:04:37Z cnteacher $
*/
///////////////////////////////////////////////////////////
//分析者：SamPeng
//分析时间：2008年11月11日14:17:01
//分析文件名：include/ftp.func.php
///////////////////////////////////////////////////////////
/**
 * 很明显了。这个是ftp的函数包
 */
if(!defined('IN_DISCUZ')) {
	exit('Access Denied');
}
//建立ftp链接的函数
function dftp_connect($ftphost, $ftpuser, $ftppass, $ftppath, $ftpport = 21, $ftpssl = 0, $silent = 0) {
	global $ftp;
	//无超时限制
	@set_time_limit(0);
	//wipespecial特殊字符替换,具体看global.func.php文件
	$ftphost = wipespecial($ftphost);
	//具体类型处理
	$ftpport = intval($ftpport);
	$ftpssl = intval($ftpssl);
	$ftp['timeout'] = intval($ftp['timeout']);
	
	//是否存在ssl链接的方法，如果不存在，则用普通的ftp_connect方法建立连接
	$func = $ftpssl && function_exists('ftp_ssl_connect') ? 'ftp_ssl_connect' : 'ftp_connect';
	//如果还是不存在ftp_connect方法。当然要报告错误了。DZ想得很周到
	if($func == 'ftp_connect' && !function_exists('ftp_connect')) {
		if($silent) {
			return -4;
		} else {
			errorlog('FTP', "FTP not supported.", 0);
		}
	}
	/**
	 * 这里的判断用到了可变变量名的技巧
	 * $func可以为ftp_connect也可以是ftp_ssl_connect
	 * 两种不同的方法。以($ftphost, $ftpport, 20)为参数进行操作。
	 * 然后获取连接id。操作成功，则继续往下。
	 */
	if($ftp_conn_id = @$func($ftphost, $ftpport, 20)) {
		if($ftp['timeout'] && function_exists('ftp_set_option')) {
			//超时后打利用ftp_set_option对ftp服务的参数进行设置
			@ftp_set_option($ftp_conn_id, FTP_TIMEOUT_SEC, $ftp['timeout']);
		}
		//登陆进入ftp
		if(dftp_login($ftp_conn_id, $ftpuser, $ftppass)) {
			//是否设置了开启被动模式传输
			if($ftp['pasv']) {
				//这里是打开被动模式传输。也就是有客户端开启传输，而不是服务器开启
				dftp_pasv($ftp_conn_id, TRUE);
			}
			//用过ftp软件的朋友都知道。。。。会有个远程路径登陆。这里就是进行这样的操作
			if(dftp_chdir($ftp_conn_id, $ftppath)) {
				//返回链接id
				return $ftp_conn_id;
			} else {
				//发生错误，也就是不存在这样的远程路径。写入日志。
				if($silent) {
					return -3;
				} else {
					errorlog('FTP', "Chdir '$ftppath' error.", 0);
				}
			}
		} else {
			//登陆失败
			if($silent) {
				return -2;
			} else {
				errorlog('FTP', '530 Not logged in.', 0);
			}
		}
	} else {
		//链接失败
		if($silent) {
			return -1;
		} else {
			errorlog('FTP', "Couldn't connect to $ftphost:$ftpport.", 0);
		}
	}
	dftp_close($ftp_conn_id);
	return -1;
}
/**
 * 在ftp下建立目录
 *
 * @param $ftp_stream ftp链接id
 * @param $directory  需要建立的ftp目录
 * @return 返回ture or false
 */
function dftp_mkdir($ftp_stream, $directory) {
	//请查看global.func.php文件此函数作用。不多解释
	$directory = wipespecial($directory);
	return @ftp_mkdir($ftp_stream, $directory);
}
/**
 * 读取目录
 *
 * @param $ftp_stream 同上
 * @param $directory 同上
 * @return true or false
 */
function dftp_rmdir($ftp_stream, $directory) {
	//请查看global.func.php文件此函数作用。不多解释
	$directory = wipespecial($directory);
	return @ftp_rmdir($ftp_stream, $directory);
}
/**
 * 上传文件到ftp
 *
 * @param  $ftp_stream 同上
 * @param  $remote_file 目标地址
 * @param  $local_file 本地地址
 * @param  $mode 传输模式参数 mode 只能为 FTP_ASCII（文本模式）或 FTP_BINARY（二进制模式）。 
 * @param  $startpos 仅适用于 PHP 4.3.0 以上版本。但这个参数用来干嘛的？
 * @return 同上
 */
function dftp_put($ftp_stream, $remote_file, $local_file, $mode, $startpos = 0 ) {
	//请查看global.func.php文件此函数作用。不多解释
	$remote_file = wipespecial($remote_file);
	$local_file = wipespecial($local_file);
	$mode = intval($mode);
	$startpos = intval($startpos);
	return @ftp_put($ftp_stream, $remote_file, $local_file, $mode, $startpos);
}
/**
 * 返回指定文件的大小
 *
 * @param  $ftp_stream 同上
 * @param  $remote_file 指定文件
 * @return 成功则返回大小，失败则返回-1
 */
function dftp_size($ftp_stream, $remote_file) {
	//请查看global.func.php文件此函数作用。不多解释
	$remote_file = wipespecial($remote_file);
	return @ftp_size($ftp_stream, $remote_file);
}
/**
 * 关闭ftp链接
 *
 * @param $ftp_stream
 * @return true or false
 */
function dftp_close($ftp_stream) {
	return @ftp_close($ftp_stream);
}
/**
 * 删除目录
 *
 * @param $ftp_stream
 * @param $path 需要删除的目录
 * @return true or false
 */
function dftp_delete($ftp_stream, $path) {
	$path = wipespecial($path);
	return @ftp_delete($ftp_stream, $path);
}

/**
 * 上面又个put是上传。那这个就是下载了
 *
 *
 * @param  $ftp_stream	
 * @param  $local_file	本地目标目录
 * @param  $remote_file	远程目录
 * @param  $mode 模式，同上面的。懒得打字了
 * @param  $resumepos 同上面的下载，懒得打字
 * @return true or false
 */
function dftp_get($ftp_stream, $local_file, $remote_file, $mode, $resumepos = 0) {
	$remote_file = wipespecial($remote_file);
	$local_file = wipespecial($local_file);
	$mode = intval($mode);
	$resumepos = intval($resumepos);
	return @ftp_get($ftp_stream, $local_file, $remote_file, $mode, $resumepos);
}
/**
 * 登陆ftp
 *
 * @param  $ftp_stream 
 * @param  $username 用户名
 * @param  $password 密码
 * @return true or false
 */
function dftp_login($ftp_stream, $username, $password) {
	$username = wipespecial($username);
	$password = str_replace(array("\n", "\r"), array('', ''), $password);
	return @ftp_login($ftp_stream, $username, $password);
}
/**
 * 返回当前 FTP 被动模式是否打开.为什么要自己重定义一个这个方法呢？
 * 方便操作？因为这里只是多了一个将$pasv返回成整数值。
 *
 * @param  $ftp_stream ftp连接id
 * @param  $pasv
 * @return 返回true或者false
 */
function dftp_pasv($ftp_stream, $pasv) {
	$pasv = intval($pasv);
	/**
	 * 粘贴手册上的说明。很容易理解。。。不解释
	 * bool ftp_pasv ( resource ftp_stream, bool pasv)
	 * 如果参数 pasv 为真，打开被动模式传输 (PASV MODE) ，否则，
	 * 如果参数 pasv 为假则关闭被动传输模式。在被动模式打开的情况下，数据的传送由客户机启动，
	 * 而不是由服务器开始。 
	 */
	return @ftp_pasv($ftp_stream, $pasv);
}
/**
 * 在 FTP 服务器上切换当前目录
 *
 * @param $ftp_stream
 * @param $directory 目标目录
 * @return true or false
 */
function dftp_chdir($ftp_stream, $directory) {
	$directory = wipespecial($directory);
	return @ftp_chdir($ftp_stream, $directory);
}
/**
 * 向服务器发送 SITE 命令.
 *
 * @param $ftp_stream
 * @param $cmd cmd命令
 * @return TRUE or false
 */
function dftp_site($ftp_stream, $cmd) {
	$cmd = wipespecial($cmd);
	return @ftp_site($ftp_stream, $cmd);
}
/**
 * 设置权限
 *
 * @param  $ftp_stream
 * @param  $mode 权限
 * @param  $filename
 * @return ture or false
 */
function dftp_chmod($ftp_stream, $mode, $filename) {
	$mode = intval($mode);
	$filename = wipespecial($filename);
	//安全判断，如果目标服务器存在ftp_chmod方法，则直接设置mode权限。
	//如果不存在，则调用dftp_site方法用cmd命令设置权限
	if(function_exists('ftp_chmod')) {
		return @ftp_chmod($ftp_stream, $mode, $filename);
	} else {
		return dftp_site($ftp_stream, 'CHMOD '.$mode.' '.$filename);
	}
}

?>